package zuoye_4_14;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Text {
	private static int j;
	public static void main(String[] args) throws Exception {
		
//		//题目一 :   生产5个 消费5个
//		ArrayBlockingQueue<String> abq=new ArrayBlockingQueue<>(5);
//		Cooker c=new Cooker(abq);
//		Foodie f=new Foodie(abq);
//		c.start();
//		f.start();
		

		
		
		
//		//题目二:子进程先执行三次，主进程再执行五次，然后这个过程执行三次
//		for (int i = 0; i < 3; i++) {
//			Thread zThread = new Thread(new ChildProcess());
//			zThread.start();
//			zThread.join();
//			for (int j = 0; j < 5; j++) { 
//				System.out.println("这里是主进程"); 
//			}
//			System.out.println("===");
//		} 
		
	
		
		
		
//		//题目三 :编写一个可以从 1 到 n 输出代表这个数字的字符串的程序
//		//如果这个数字可以被 3 整除，输出 "fizz"。
//		//如果这个数字可以被 5 整除，输出 "buzz"。
//		//如果这个数字可以同时被 3 和 5 整除，输出 "fizzbuzz"。
//		//线程A将调用 fizz() 来判断是否能被 3 整除，如果可以，则输出 fizz。
//		//线程B将调用 buzz() 来判断是否能被 5 整除，如果可以，则输出 buzz。
//		//线程C将调用 fizzbuzz() 来判断是否同时能被 3 和 5 整除，如果可以，则输出 fizzbuzz。
//		//线程D将调用 number() 来实现输出既不能被 3 整除也不能被 5 整除的数字
//		int n = 17;
//		
//		FizzBuzz fizzBuzz = new FizzBuzz(n);
//
//		Thread threadA = new Thread(() -> {
//		    try {
//		        fizzBuzz.fizz(() -> System.out.print("fizz, "));
//		    } catch (InterruptedException e) {
//		        e.printStackTrace();
//		    }
//		});
//
//		Thread threadB = new Thread(() -> {
//		    try {
//		        fizzBuzz.buzz(() -> System.out.print("buzz, "));
//		    } catch (InterruptedException e) {
//		        e.printStackTrace();
//		    }
//		});
//
//		Thread threadC = new Thread(() -> {
//		    try {
//		        fizzBuzz.fizzbuzz(() -> System.out.print("fizzbuzz, "));
//		    } catch (InterruptedException e) {
//		        e.printStackTrace();
//		    }
//		});
//
//		Thread threadD = new Thread(() -> {
//		    try {
//		        fizzBuzz.number((num) -> System.out.print(num + ", "));
//		    } catch (InterruptedException e) {
//		        e.printStackTrace();
//		    }
//		});
//
//		threadA.start();
//		threadB.start();
//		threadC.start();
//		threadD.start();


		
		
//		//题目四
//		//写两个线程，一个线程打印1~ 52，另一个线程打印A~Z，打印顺序是12A34B…5152Z
//		Object lock = new Object();
//		printaz p2 = new printaz(lock);
//		Print151 p1 = new Print151(lock);
//		p1.start();
//		p2.start();
		
		
		
		
////		题目五
////		使用多线程实现多个文件同步复制功能，并在控制台显示复制的进度，
////		进度以百分比表示。例如：把文件A复制到E盘某文件夹下，在控制台上显示“XXX文件已复制10%”，
////		“XXX文件已复制20%”……“XXX文件已复制100%”，“XXX复制完成！”
////		A文件复制了10%
////		A文件复制了20%
////		B文件复制10%
////		A文件复制30%
////		C文件复制10%
////		B文件复制20%
//		Path sourcePath1 = Paths.get("E:\\zhuo_main_fang_zhi\\aaa\\a\\a.txt");
//		Path sourcePath2 = Paths.get("E:\\zhuo_main_fang_zhi\\aaa\\a\\b.txt");
//		Path destinationPath1 = Paths.get("E:\\zhuo_main_fang_zhi\\aaa\\b\\a.txt");
//		Path destinationPath2 = Paths.get("E:\\zhuo_main_fang_zhi\\aaa\\b\\b.txt");
//		FileCopy f = new FileCopy();
//		ExecutorService executor = Executors.newFixedThreadPool(2);
//		 // 提交复制任务到线程池
//        executor.submit(() -> {
//            f.copyFile(sourcePath1, destinationPath1);
//        });
//        executor.submit(() -> {
//            f.copyFile(sourcePath2, destinationPath2);
//        });
//
//        executor.shutdown();
		
		
		
		
////		题目六:设计4个线程，其中两个线程每次对j增加1，另外两个线程对j每次减少1。
////		考虑到线程的安全性写出程序。（不要使用atomaicInteger 来做）
//		 for (int i = 0; i < 2; i++) {
//	            new Thread(new Add()).start();
//	            new Thread(new Subtract()).start();
//	        }
//	    }
//
//	    private static synchronized void add() {
//	        j++;
//	        System.out.println("j="+j);
//	    }
//
//	    private static synchronized void subtract() {
//	        j--;
//	        System.out.println("j="+j);
//	    }
//
//	    private static class Add implements Runnable {
//	        public void run() {
//	            for (int i = 0; i < 100; i++) {
//	                add();
//	            }
//	        }
//	    }
//
//	    private static class Subtract implements Runnable {
//	        public void run() {
//	            for (int i = 0; i < 100; i++) {
//	                subtract();
//	            }
//	        }
//		
		
		
		
		
		
		
		/*
		 * 题目七:现有函数 printNumber 可以用一个整数参数调用，并输出该整数到控制台。
		 * 
		 * 例如，调用 printNumber(7) 将会输出 7 到控制台。 给你类 ZeroEvenOdd 的一个实例，
		 * 该类中有三个函数：zero、even 和
		 * odd 。ZeroEvenOdd 的相同实例将会传递给三个不同线程：
		 * 
		 * 线程 A：调用 zero() ，只输出 0 线程 B：调用 even() ，只输出偶数 线程 C：
		 * 调用 odd() ，只输出奇数 修改给出的类，以输出序列
		 * "010203040506..." ，其中序列的长度必须为 2n 。
		 * 
		 * 实现 ZeroEvenOdd 类：
		 * ZeroEvenOdd(int n) 用数字 n 初始化对象，表示需要输出的数。 
		 * void zero(printNumber) 调用printNumber 以输出一个 0 。 
		 * void even(printNumber) 调用printNumber 以输出偶数。 void
		 * odd(printNumber) 调用 printNumber 以输出奇数。  
		 * 
		 * 示例 1：
		 * 
		 * 输入：n = 2 输出："0102" 解释：三条线程异步执行，其中一个调用 zero()，
		 * 另一个线程调用 even()，最后一个线程调用odd()。正确的输出为 "0102"。 
		 * 示例 2：
		 * 
		 * 输入：n = 5 输出："0102030405"
		 */
		 int n = 8;
	        ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(n);

	        Thread t1 = new Thread(() -> {
	            try {
	                zeroEvenOdd.zero(System.out::print);
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
	        });

	        Thread t2 = new Thread(() -> {
	            try {
	                zeroEvenOdd.even(System.out::print);
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
	        });

	        Thread t3 = new Thread(() -> {
	            try {
	                zeroEvenOdd.odd(System.out::print);
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
	        });

	        t1.start();
	        t2.start();
	        t3.start();

	        try {
	            t1.join();
	            t2.join();
	            t3.join();
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
	    }
		
		

		
	}
	
	
